#include <iostream>
using namespace std;
class AbstractionImp{
public:
    AbstractionImp(){}
    virtual void Operation()=0;
    virtual ~ AbstractionImp(){
        cout<<"AbstractionImpDelete"<<endl;
    }
};
class ConcreateA:public AbstractionImp{
public:
    void Operation(){
        cout<<"ConcreateAOperation"<<endl;
    }
    ~ ConcreateA(){
        cout<<"ConcreateADelete"<<endl;
    }
};
class ConcreateB:public AbstractionImp{
public:
    void Operation(){
        cout<<"ConcreateBOperation"<<endl;
    }
    ~ ConcreateB(){
        cout<<"ConcreateBDelete"<<endl;
    }
};
class Abstraction{
protected:
    AbstractionImp * abstractionImp;
public:
    Abstraction(AbstractionImp * abstractionImp){
        this->abstractionImp = abstractionImp;

    }
    Abstraction(){}
    virtual void Operation()=0;
    virtual ~ Abstraction(){
        cout<<"AbstrationDelete"<<endl;
    }
};
class DefinedAbstractionA:public Abstraction{
public:
    DefinedAbstractionA(AbstractionImp * t):Abstraction(t){
        abstractionImp = t;
    }
    void Operation(){
        abstractionImp->Operation();
        //Abstraction::Operation();
    }

};
class DefinedAbstractionB:public Abstraction{
public:
    DefinedAbstractionB(AbstractionImp * t):Abstraction(t){
        abstractionImp = t;
    }
    void Operation(){
        abstractionImp->Operation();
        //Abstraction::Operation();
    }

};
int main() {
    ConcreateB * b = new ConcreateB();
    Abstraction * abstraction = new DefinedAbstractionA(b);
    abstraction->Operation();
    delete(abstraction);
    delete(b);
}